<template>
  <DialogCom :draggable="true" :title="title" :width="'500'" :visible="isVisible" @close="close" @confirm="confirm">
    <template v-slot:content>
      <el-form ref="ruleFormRef" :model="formData" :rules="rules" label-width="90px" class="demo-ruleForm" status-icon>
        <el-form-item label="文件:" prop="geojson">
          <div class="path">
            <el-input v-model="formData.geojson" placeholder="上传GeoJSON文件" disabled />
            <input v-show="false" ref="upfileRef" type="file" title=" " @change="upLoadFile"
              accept=".geojson,application/geo+json,geojson文件,GeoJSON 文件" multiple="multiple" style="display: none" />
            <el-button class="common-btn" @click="selectFile">上传</el-button>
          </div>
        </el-form-item>
        <el-form-item label="高程:" prop="height" v-if="type == 'HeightMask'">
          <el-input v-model="formData.height" type="number" :step="1" :min="0" @change="editHandle" />
        </el-form-item>

        <el-form-item label="柱体高度:" prop="cylinderHeight" v-if="type == 'ClipFlat'">
          <el-input v-model="formData.cylinderHeight" type="number" :step="1" :min="0" @change="editCylinderHeight" />

        </el-form-item>
        <el-form-item label="编辑模式:" prop="operation" v-if="type == 'ClipFlat'">
          <el-select v-model="formData.operation" placeholder="请选择编辑模式">
            <el-option v-for="item in operationMode" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
      </el-form>
    </template>
  </DialogCom>
  <FileServer v-if="currentDialog == 'file'" @close="currentDialog = undefined" @confirm="fileConfirm"
    :fileAccept="'geojson数据(*.geojson)|*.geojson'" />
</template>

<script setup>
import { ref, defineProps } from 'vue'
import DialogCom from '@/components/common/DialogCom.vue'
import { ElMessage } from 'element-plus'
import FileServer from '@/components/FileServer.vue'
import { getOs, reqGetFileContent } from "@/api/modelser2Api";
import { isLocalhost } from "@/scripts/utils";
import loading from "@/api/loading";

const currentDialog = ref(undefined)

// 上传文件
const upfileRef = ref(null)
let arr = []
let fromDataArr = []
const selArr = ref([])
const ruleFormRef = ref('')
const props = defineProps({
  isVisible: {
    type: Boolean,
    default: false,
  },
  close: {
    type: Boolean,
    default: false,
  },
  title: {
    type: String,
    default: '',
  },
  type: {
    type: String,
    default: '',
  },
})
const emits = defineEmits(['close', 'confirm'])
const formData = ref({
  geojson: '',
  serverPath: '',
  features: '',
  height: 0,
  operation: "1",
  cylinderHeight: 10
})

const rules = ref({
  geojson: [{ required: true, message: '请上传GeoJSON文件', trigger: 'blur' }],
  height: [{ required: true, message: '请输入高程', trigger: 'blur' }],
  cylinderHeight: [{ required: true, message: '请输入柱体高度', trigger: 'blur' }],
  operation: [{ required: true, message: '请选择编辑模式', trigger: 'blur' }],
})

const selectFile = async () => {
  const res = await getOs()
  if ((await getOs()) == 'win' && isLocalhost) {
    upfileRef.value.click()
  } else {
    currentDialog.value = 'file'
  }
}
// 裁剪方式
const operationMode = [
  {
    value: "1",
    label: "裁剪",
  },
  {
    value: "2",
    label: "压平",
  },
  // {
  //   value: "3",
  //   label: "单体化",
  // },
];

const editHandle = (value) => {
  // 将输入值强制转换为数字，并确保不小于 0.1
  const numValue = Number(value);
  if (numValue <= 0 || isNaN(numValue)) {
    formData.value.height = 0
  }
}

const editCylinderHeight = (value) => {
  // 将输入值强制转换为数字，并确保不小于 0.1
  const numValue = Number(value);
  if (numValue <= 0 || isNaN(numValue)) {
    formData.value.cylinderHeight = 0
  }
}

/**
 * 选择的文件路径
 * @param path
 */
const fileConfirm = async (path) => {
  try {
    const arr = path.split('\\')
    const res = await reqGetFileContent(encodeURIComponent(path))
    if (res.status != "ok") {
      loading.closeLoading()
      return;
    }
    loading.closeLoading()
    const geojson = JSON.parse(res.data)
    verificationGeoJSON(geojson, arr[arr.length - 1])
  } catch (error) {
    loading.closeLoading()
    console.log(error)
  }
  currentDialog.value = undefined
}

const upLoadFile = async (e) => {
  console.log(e);

  const files = e.target.files
  if (files.length === 0) return

  // 重置状态
  formData.value.geojson = ''
  formData.value.features = ''

  const file = files[0]

  // 验证文件类型
  const allowedExtensions = ['.geojson', '.json']
  const allowedTypes = ['application/geo+json', 'application/json']
  const fileName = file.name.toLowerCase()
  const fileType = file.type.toLowerCase()

  // 检查文件扩展名和MIME类型
  const isValidExtension = allowedExtensions.some(ext => fileName.endsWith(ext))
  const isValidType = allowedTypes.includes(fileType) || fileType === '' // 某些浏览器可能返回空类型

  if (!isValidExtension && !isValidType) {
    ElMessage.error('请选择GeoJSON文件（.geojson 或 .json 格式）')
    // 清空文件输入
    e.target.value = ''
    return
  }

  const reader = new FileReader()

  reader.onload = (event) => {
    try {
      const content = event.target.result
      const geojson = JSON.parse(content)

      verificationGeoJSON(geojson, file.name)
    } catch (error) {
      ElMessage.error(`文件错误: ${error.message}`)
      console.error('GeoJSON解析错误:', error)
      // 清空文件输入
      e.target.value = ''
    }
  }

  reader.onerror = () => {
    ElMessage.error('文件读取失败，请重试')
    e.target.value = ''
  }

  reader.readAsText(file)
}

// 验证geojson逻辑
const verificationGeoJSON = (geojson, name) => {
  console.log("geojson", geojson);

  // 验证是否包含Polygon
  if (!containsPolygon(geojson)) {
    throw new Error('文件中未包含任何Polygon类型的地理数据')
  }

  // 验证是否为有效的GeoJSON结构
  if (!isValidGeoJSON(geojson)) {
    throw new Error('文件不是有效的GeoJSON格式')
  }

  // 更新表单数据
  formData.value.geojson = name
  // 处理不同类型的GeoJSON结构
  let features = []
  if (geojson.type === 'FeatureCollection') {
    features = geojson.features || []
  } else if (geojson.type === 'Feature') {
    features = [geojson]
  } else if (geojson.type === 'GeometryCollection') {
    // 将GeometryCollection转换为Feature数组
    features = (geojson.geometries || []).map(geometry => ({
      type: 'Feature',
      properties: {},
      geometry
    }))
  } else if (geojson.type === 'Polygon' || geojson.type === 'MultiPolygon') {
    // 将几何对象转换为Feature
    features = [{
      type: 'Feature',
      properties: {},
      geometry: geojson
    }]
  }

  // 过滤并转换多边形特征
  formData.value.features = features.filter(feature => {
    return feature &&
      feature.geometry &&
      (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiPolygon')
  }).flatMap(feature => {
    const geometry = feature.geometry

    if (geometry.type === 'Polygon') {
      // 处理普通Polygon
      return {
        exterior: geometry.coordinates[0], // 外环
        interiors: geometry.coordinates.slice(1) // 内环（孔洞）
      }
    } else if (geometry.type === 'MultiPolygon') {
      // 处理MultiPolygon - 展平为多个多边形
      return geometry.coordinates.flatMap(polygonCoords => {
        if (polygonCoords.length === 0) return []

        return {
          exterior: polygonCoords[0], // 每个多边形的外环
          interiors: polygonCoords.slice(1) // 每个多边形的内环
        }
      })
    }
    return []
  })

  console.log("解析后的特征:", formData.value.features)
  ElMessage.success(`GeoJSON文件验证通过，包含${formData.value.features.length}个多边形`)
}

// 验证是否为有效的GeoJSON结构
const isValidGeoJSON = (data) => {
  try {
    if (typeof data !== 'object' || data === null) return false

    // 检查基本GeoJSON类型
    const validTypes = ['FeatureCollection', 'Feature', 'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon', 'GeometryCollection']
    if (!validTypes.includes(data.type)) return false

    // 根据类型进行更详细的验证
    switch (data.type) {
      case 'FeatureCollection':
        return Array.isArray(data.features)
      case 'Feature':
        return data.geometry && typeof data.geometry === 'object'
      case 'GeometryCollection':
        return Array.isArray(data.geometries)
      default: // 几何类型
        return Array.isArray(data.coordinates)
    }
  } catch {
    return false
  }
}

// 验证是否包含Polygon类型的GeoJSON
const containsPolygon = (data) => {
  try {
    // 基本结构检查
    if (typeof data !== 'object' || data === null) {
      return false
    }
    if (!('type' in data)) {
      return false
    }

    // 检查FeatureCollection
    if (data.type === 'FeatureCollection') {
      if (!Array.isArray(data.features) || data.features.length === 0) {
        return false
      }

      // 检查是否至少有一个Polygon或MultiPolygon
      return data.features.some(feature => {
        return feature &&
          feature.geometry &&
          (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiPolygon')
      })
    }

    // 检查单个Feature
    if (data.type === 'Feature') {
      return data.geometry &&
        (data.geometry.type === 'Polygon' || data.geometry.type === 'MultiPolygon')
    }

    // 检查单个几何对象
    if (data.type === 'Polygon' || data.type === 'MultiPolygon') {
      return true
    }

    // 检查GeometryCollection
    if (data.type === 'GeometryCollection' && Array.isArray(data.geometries)) {
      return data.geometries.some(geometry =>
        geometry && (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon')
      )
    }

    return false
  } catch {
    return false
  }
}

const close = () => {
  emits('close')
}
// 确认
const confirm = () => {
  ruleFormRef.value.validate((valid) => {
    if (!valid) return
    emits('confirm', {
      features: formData.value.features,
      height: Number(formData.value.height),
      operation: formData.value.operation,
      cylinderHeight: Number(formData.value.cylinderHeight),
    })
  })
}
</script>

<style scoped>
.el-form-item .el-textarea,
.el-form-item .el-select,
.el-form-item .el-input {
  width: 300px !important;
}

.item {
  width: 300px;
}

.path {
  display: grid;
  grid-template-columns: 300px 70px;
  grid-column-gap: 5px;
}
</style>
